package cn.lhn.ridersclub.service;

import cn.lhn.ridersclub.dto.ClubDto;
import cn.lhn.ridersclub.dto.ClubGradeDto;
import cn.lhn.ridersclub.dto.ClubItemDto;
import cn.lhn.ridersclub.entity.*;
import cn.lhn.ridersclub.mapper.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

@Service
public class ClubServiceImpl implements ClubService {

    private final ClubMapper clubMapper;

    private final AccountMapper accountMapper;

    private final ClubGradeMapper clubGradeMapper;

    private final ClubFollowMapper clubFollowMapper;

    private final WantMapper wantMapper;

    private final PaperMapper paperMapper;

    private final ClubFollowService clubFollowService;

    private final RedisService redisService;

    public ClubServiceImpl(ClubMapper clubMapper, AccountMapper accountMapper, ClubGradeMapper clubGradeMapper, ClubFollowMapper clubFollowMapper, WantMapper wantMapper, PaperMapper paperMapper, ClubFollowService clubFollowService, RedisService redisService) {
        this.clubMapper = clubMapper;
        this.accountMapper = accountMapper;
        this.clubGradeMapper = clubGradeMapper;
        this.clubFollowMapper = clubFollowMapper;
        this.wantMapper = wantMapper;
        this.paperMapper = paperMapper;
        this.clubFollowService = clubFollowService;
        this.redisService = redisService;
    }

    @Override
    public ClubDto getClub(Long id) {
        return toClubDto(clubMapper.selectById(id));
    }

    @Override
    public List<ClubDto> getClub(String clubName) {
        QueryWrapper<Club> qw = new QueryWrapper<>();
        qw.like("club_name", clubName);
        return toClubDtoList(clubMapper.selectList(qw));
    }

    @Override
    public List<ClubDto> getByClassify(String classify) {
        QueryWrapper<Club> qw = new QueryWrapper<>();
        qw.like("classify", classify);
        return toClubDtoList(clubMapper.selectList(qw));
    }

    @Override
    public List<ClubDto> getClubs() {
        return toClubDtoList(clubMapper.selectList(null));
    }

    @Override
    public void addWant(Long clubId, Long accountId) {

        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        Club club = clubMapper.selectById(clubId);
        if (club == null) {
            throw new RuntimeException("车友会不存在");
        }

        QueryWrapper<Want> qw = new QueryWrapper<>();
        qw.eq("account_id", accountId);
        qw.eq("club_id", clubId);
        Want want = wantMapper.selectOne(qw);
        if (want != null) {
            throw new RuntimeException("请勿重复提交");
        }

        wantMapper.insert(Want
                .builder()
                .id(null)
                .accountId(accountId)
                .clubId(clubId)
                .build());
    }

    @Override
    public void deleteWant(Long clubId, Long accountId) {


        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        Club club = clubMapper.selectById(clubId);
        if (club == null) {
            throw new RuntimeException("车友会不存在");
        }

        QueryWrapper<Want> qw = new QueryWrapper<>();
        qw.eq("account_id", accountId);
        qw.eq("club_id", clubId);
        Want want = wantMapper.selectOne(qw);
        if (want == null) {
            throw new RuntimeException("记录不存在");
        }

        wantMapper.deleteById(want.getId());
    }

    @Override
    public Boolean isWant(Long clubId, Long accountId) {
        QueryWrapper<Want> qw = new QueryWrapper<>();
        qw.eq("club_id", clubId);
        qw.eq("account_id", accountId);
        Want want = wantMapper.selectOne(qw);
        return want != null;
    }

    @Override
    public void postGrade(Long clubId, Long accountId, Long grade) {


        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        Club club = clubMapper.selectById(clubId);
        if (club == null) {
            throw new RuntimeException("车友会不存在");
        }

        QueryWrapper<ClubGrade> qw = new QueryWrapper<>();
        qw.eq("club_id", clubId);
        qw.eq("account_id", accountId);
        ClubGrade one = clubGradeMapper.selectOne(qw);
        if (one != null) {
            throw new RuntimeException("请勿重复提交");
        }

        if (grade < 1 || grade > 5) {
            throw new RuntimeException("请选择正确的评分");
        }

        clubGradeMapper.insert(ClubGrade
                .builder()
                .id(null)
                .clubId(clubId)
                .accountId(accountId)
                .grade(grade)
                .build());
    }

    @Override
    public Boolean isPostGrade(Long clubId, Long accountId) {
        QueryWrapper<ClubGrade> qw = new QueryWrapper<>();
        qw.eq("club_id", clubId);
        qw.eq("account_id", accountId);
        return clubGradeMapper.selectOne(qw) != null;
    }

    @Override
    public List<Long> list3FansId(Long clubId) {
        List<Long> list = clubFollowMapper.list3FansId(clubId);
        return list == null ? new ArrayList<>() : list;
    }

    @Override
    public List<Long> listBannerClubId() {
        List<Object> ol = redisService.lRange("banner:id", 0L, -1L);
        List<Long> list = new ArrayList<>();
        if (ol == null) {
            return list;
        }
        for (Object o : ol) {
            try {
                list.add(Long.parseLong(o.toString()));
            }
            catch (Exception ignore) {}
        }
        return list;
    }

    @Override
    public List<ClubItemDto> listClubByClassify(String classify) {
        QueryWrapper<Club> qw = new QueryWrapper<>();
        qw.eq("classify", classify);
        List<Club> list = clubMapper.selectList(qw);
        List<ClubItemDto> l = new ArrayList<>();
        for (Club club : list) {

            QueryWrapper<Paper> qwp = new QueryWrapper<>();
            qwp.eq("club_id", club.getId());
            Long count = paperMapper.selectCount(qwp);

            ClubItemDto dto = ClubItemDto
                    .builder()
                    .id(club.getId())
                    .name(club.getClubName())
                    .paperCount(count)
                    .build();
            l.add(dto);
        }

        return l;
    }

    public List<ClubDto> toClubDtoList(List<Club> list) {
        if (list == null) {
            return new ArrayList<>();
        }

        List<ClubDto> dtoList= new ArrayList<>();
        for (Club club : list) {
            if (club != null) {
                dtoList.add(toClubDto(club));
            }
        }
        return dtoList;
    }

    public ClubDto toClubDto(Club club) {
        if (club == null) {
            return null;
        }

        //  粉丝数
        Long fansCount = clubFollowService.getFansCount(club.getId());

        //  评分
        QueryWrapper<ClubGrade> qw = new QueryWrapper<>();
        qw.eq("club_id", club.getId());
        List<ClubGrade> gradeList = clubGradeMapper.selectList(qw);
        Map<Long, Long> map = new Hashtable<>();
        for (ClubGrade grade : gradeList) {
            Long count = map.get(grade.getGrade());
            if (count == null) {
                count = 0L;
            }
            map.put(grade.getGrade(), count + 1);
        }
        Long v5 = map.get(5L);
        Long v4 = map.get(4L);
        Long v3 = map.get(3L);
        Long v2 = map.get(2L);
        Long v1 = map.get(1L);
        ClubGradeDto clubGradeDto = ClubGradeDto
                .builder()
                .clubId(club.getId())
                .v5(v5 == null ? 0L : v5)
                .v4(v4 == null ? 0L : v4)
                .v3(v3 == null ? 0L : v3)
                .v2(v2 == null ? 0L : v2)
                .v1(v1 == null ? 0L : v1)
                .build();

        //  评分人数
        QueryWrapper<ClubGrade> qwcg = new QueryWrapper<>();
        qwcg.eq("club_id", club.getId());
        Long postCount = clubGradeMapper.selectCount(qwcg);

        //  想要的人数
        QueryWrapper<Want> qww = new QueryWrapper<>();
        qww.eq("club_id", club.getId());
        Long wantCount = wantMapper.selectCount(qww);

        //  文章个数
        QueryWrapper<Paper> qwp = new QueryWrapper<>();
        qwp.eq("club_id", club.getId());
        Long paperCount = paperMapper.selectCount(qwp);

        return ClubDto
                .builder()
                .id(club.getId())
                .name(club.getClubName())
                .classify(club.getClassify())
                .fansCount(fansCount)
                .clubGradeDto(clubGradeDto)
                .wantCount(wantCount)
                .paperCount(paperCount)
                .postCount(postCount)
                .build();
    }
}
